home *** CD-ROM | disk | FTP | other *** search
/ BBS Toolkit / BBS Toolkit.iso / doors_2 / triv201.zip / TRIVIA.C < prev    next >
C/C++ Source or Header  |  1992-07-16  |  28KB  |  978 lines

  1. /***************************************************************************
  2.  *   TRIVIA.C                                                              *
  3.  *   Copyright (C) 1991 A - Z Computer Solutions.   All Rights Reserved.   *
  4.  *   Trivia                                        - RDWild, August 1991   *
  5.  ***************************************************************************/
  6.  
  7. #include "stdio.h"
  8. #include "ctype.h"
  9. #include "trivia.h"
  10. #include "majorbbs.h"
  11. #include "usracc.h"
  12. #include "dosface.h"
  13. #include "portable.h"
  14. #include "btvstf.h"
  15.  
  16. /* Do NOT change the ver number below */
  17. static char ver[]={"Version 2.01 01/12/92 16:57:29"};   /* Version number */
  18.  
  19. int initrv(),trivia(),triviasts(), trvclean(),trvshd();
  20.  
  21. #define TRVSTT      31        /* Trivia State */
  22. struct module module31={      /* module interface block */
  23.     '*',                  /* main menu select character (config'able) */
  24.     "",                   /* description for main menu  (config'able) */
  25.     initrv,                      /* system initialization routine     */
  26.     NULL,                        /* user logon supplemental routine   */
  27.     trivia,                      /* input routine if selected         */
  28.     triviasts,                   /* status-input routine if selected  */
  29.     NULL,                        /* hangup (lost carrier) routine     */
  30.     trvclean,                    /* midnight cleanup routine          */
  31.     NULL,                        /* delete-account routine            */
  32.     trvshd,                      /* finish-up (sys shutdown) routine  */
  33. };
  34.  
  35. static FILE *trvmb;     /* Trivia configuration variables */
  36. static BTVFILE *btvquest, *btvusrinfo, *btvhscore;  /* Btrieve file pointer for control file */
  37.  
  38. struct trvquest {                       /* Question data block for btv file     */
  39.     long questnum;                  /*   Key for Btrieve */
  40.     char approv;                    /*   A = Approved, U = Unapproved       */
  41.     char question[80];              /*   question                           */
  42.     char answer[40];                /*   answer to question.                */
  43.     char userid[UIDSIZ];    /* Userid who wrote question          */
  44.     char spare[255-134];    /* space for graceful upgrade, Do NOT use! */
  45. } *trvquest;
  46.  
  47. struct trvusrinfo {                     /* Info about user */
  48.     char userid[UIDSIZ];            /* User-id name */
  49.     long score;                     /* Current score of user */
  50.     int plays;                      /* Number of Plays today? */
  51.     char spare[128-15];             /* Space for graceful upgrade, Do NOT use! */
  52. } *trvusrinfo;
  53.  
  54. #define TIMEOUT 1
  55.  
  56. struct trvusr {                         /* Data block of info for each user */
  57.     long score;                             /* Current score of user. */
  58.     char question[80];                      /* Question */
  59.     char answer[40];                        /* Answer to Question! */
  60.     FILE *tfp;                              /* File Ptr for use with instructions */
  61.     int plays;                              /* Number of plays today! */
  62.     int flags;
  63. } *trvusr;
  64.  
  65. #define SCORENUM        10
  66.  
  67. struct trvhscore {                                      /* Hi Scores database info */
  68.     char sdummy;                                    /* Dummy field for Btrieve */
  69.     long score[SCORENUM];                   /* List of hi scores */
  70.     char userid[SCORENUM][UIDSIZ];  /* List of Userids for Hi Scores */
  71.     int htime[SCORENUM];                    /* Time user reached high score */
  72.     int hdate[SCORENUM];                    /* Date user reached high score */
  73.     long curquest;                         /* The Current Question Number */
  74.     long lastquest;                   /* The Last Question in the Database */
  75.     int resetdays;                                      /* Number of days before Score is Rest */
  76.     char sspare[255-163];                /* Spare Space for gracful upgrade */
  77. } *trvhscore;
  78.  
  79. int nlvtrv;                             /* allow non-live users to play Trivia? */
  80. int tnplay;                             /* Number of Plays per Day allowed */
  81. int trvscor1, trvscor2, trvscor3;       /* Configurable Score for right Quest */
  82. int trvtmout;                           /* TimeOut Time for Game */
  83. int scoredays;                          /* Number of days for Rest of Score */
  84. int trvtime[256];                       /* Allocate time units based on number of users */
  85. int vmode;                              /* Current Validation Direction */
  86. long curuquest = 0;             /* current unvalidated question number */
  87.  
  88. #define VMFIRST 1
  89. #define VMNEXT          2
  90. #define VMPREV          4
  91. #define VMFIND          8
  92. #define VMAPPR          16
  93. #define VMUNAP          32
  94. #define VMDEL           64
  95.  
  96. rttrv() /* Real Time Kick for Trivia Time Outs */
  97. {
  98.     int i;
  99.  
  100.     for (i=0; i<(nterms); i++) {
  101.         if (trvtime[i] != 0) {
  102.             trvtime[i]--;
  103.             if (trvtime[i] == 0) btuinj(i, 249);
  104.         }
  105.     }
  106.     rtkick(1, rttrv);
  107. }
  108.  
  109. initrv()                                        /* initialize Trivia stuff */
  110. {
  111.  
  112.     trvmb=opnmsg("TRIVIA.MCV");
  113.     nlvtrv=ynopt(NLVTRV);
  114.     tnplay=numopt(TNPLAY, 0, 10);   /* 0 = Unlimited Number of Plays per day */
  115.     trvscor1=numopt(TSCOR1, -32767, 32767);
  116.     trvscor2=numopt(TSCOR2, -32767, 32767);
  117.     trvscor3=numopt(TSCOR3, -32767, 32767);
  118.     trvtmout=numopt(TRVOUT, 0, 32767); /* Amount of Time before TimeOut */
  119.     scoredays=numopt(TRVRSC, 0, 365);
  120.     inimid(TRVSTT,TRVSEL,TRVMNU);
  121.  
  122.     trvhscore=(struct trvhscore *)alcmem(sizeof(struct trvhscore));
  123.     btvhscore=opnbtv("trvhscor.dat", sizeof(struct trvhscore));
  124.     if (!alobtv(trvhscore,0)) {
  125.         setmem(trvhscore,sizeof(struct trvhscore),0);
  126.         insbtv(trvhscore);
  127.     } else gcrbtv(trvhscore, 0);
  128.  
  129.     trvquest=(struct trvquest *)alcmem(sizeof(struct trvquest));
  130.     btvquest=opnbtv("trvquest.dat",sizeof(struct trvquest));
  131.     if (alobtv(trvquest, 0)) {
  132.         if (trvquest->questnum == 0) {    /* Database Needs Converting from old Format */
  133.             delbtv();
  134.             trvhscore->lastquest=0;
  135.             do {
  136.                 trvhscore->lastquest++;
  137.             } while (acqbtv(trvquest, &trvhscore->lastquest, 0));
  138.         }
  139.     }
  140.  
  141.     if (trvhscore->lastquest == 0) {
  142.         trvhscore->lastquest = 1;
  143.         while (acqbtv(trvquest, &trvhscore->lastquest, 0)) {
  144.             trvhscore->lastquest++;
  145.         }
  146.     }
  147.  
  148.     trvusrinfo=(struct trvusrinfo *)alcmem(sizeof(struct trvusrinfo));
  149.     btvusrinfo=opnbtv("trvuser.dat",sizeof(struct trvusrinfo));
  150.  
  151.     dclvda(sizeof(struct trvusr));
  152.     setmem(trvtime,(sizeof(int) * nterms-1),0);
  153.     rtkick(1, rttrv);
  154. }
  155.  
  156. void sendlmenu(void)            /* Send Long Menu to User */
  157. {
  158.     btuxmt(usrnum,"");
  159.     prfmsg(HELLO);
  160.     prf("     %s\r\r", ver);
  161.     if (usrptr->flags&ISYSOP) {
  162.         prfmsg(TMENUS);
  163.     } else {
  164.         prfmsg(TMENU);
  165.     }
  166.     usrptr->substt=1;
  167.     return;
  168. }
  169.  
  170. void sendsmenu(void)            /* Send Short Menu to User */
  171. {
  172.     if (usrptr->flags&ISYSOP) {
  173.         prfmsg(TMENUS2);
  174.     } else {
  175.         prfmsg(TMENU2);
  176.     }
  177.     usrptr->substt=1;
  178.     return;
  179. }
  180.  
  181. savequest()                             /* Save a new question to drive */
  182. {
  183.     setbtv(btvquest);
  184.     trvhscore->lastquest++;
  185.     if (trvhscore->curquest == 0 || trvhscore->curquest > trvhscore->lastquest) trvhscore->curquest=1;
  186.     setmem(trvquest,sizeof(struct trvquest),0);
  187.     trvquest->questnum = trvhscore->lastquest;
  188.     if (usrptr->flags&ISYSOP) {
  189.         trvquest->approv = 'A';
  190.     } else {
  191.         trvquest->approv = 'U';
  192.     }
  193.     strcpyd(trvquest->question, trvusr->question, 1, sizeof(trvusr->question));
  194.     strcpyd(trvquest->answer, trvusr->answer, 1, sizeof(trvusr->answer));
  195.     memcpy(trvquest->userid, usaptr->userid, UIDSIZ);
  196.     dinsbtv(trvquest);
  197. }
  198.  
  199. int strcpyd(char *dest, char *source, int start, int length)
  200. {
  201.     int curr;
  202.     int strsize;
  203.  
  204.     strsize = sizeof(source);
  205.     if (strsize > length+start) return(0);
  206.     for (curr=start; curr<=(length+start); curr++) {
  207.         dest[curr-start] = source[curr];
  208.     }
  209.     return(1);      /* Return 1=work done 0=Error */
  210. }
  211.  
  212. getquest(char rtype) /* Get a question from drive */
  213. {
  214.     setbtv(btvquest);
  215.     if (trvhscore->lastquest == 0) return(0);
  216.     setmem(trvquest,sizeof(struct trvquest),0);
  217.     switch(rtype) {
  218.         case 'A':
  219.             do {
  220.              if (trvhscore->curquest > trvhscore->lastquest) trvhscore->curquest=1;
  221.              acqbtv(trvquest, &trvhscore->curquest, 0);
  222.              trvhscore->curquest++;
  223.             } while (trvquest->approv != 'A');
  224.             break;
  225.  
  226.         case 'U':       /* Get Unvalidated Question */
  227.             do {
  228.                 acqbtv(trvquest, &curuquest, 0);
  229.                 curuquest++;
  230.         } while (trvquest->approv != 'U' && curuquest <= trvhscore->lastquest);
  231.           if (curuquest >= trvhscore->lastquest) {
  232.                 curuquest=0;
  233.                 return(0);
  234.             }
  235.             break;
  236.  
  237.         case 'D':
  238.             return(0);
  239.     }
  240.     memcpy(trvusr->question, trvquest->question, sizeof(trvusr->question));
  241.     memcpy(trvusr->answer, trvquest->answer, sizeof(trvusr->answer));
  242.     return(1);
  243. }
  244.  
  245. showquest(int questime)     /* Show what the answer would look like with chars */
  246. {                       /* ie. the work 'Coke and Pepsi' would look like */
  247.             /* 'xxxx xxx xxxxx' */
  248.  
  249.     int x;
  250.  
  251.     btuxnf(usrnum, 0, 19);
  252.     btuxmt(usrnum,"");
  253.     prfmsg(TASKQES, questime, trvusr->question);
  254.     btumil(usrnum, strlen(trvusr->answer));
  255.     for (x=0; x<=(strlen(trvusr->answer)-1); x++) {
  256.         if (trvusr->answer[x] > 'A' || trvusr->answer[x] < 'z') {
  257.             if (trvusr->answer[x] == ' ') {
  258.                 prf("%c", trvusr->answer[x]);
  259.             } else prf("x");
  260.         }
  261.     }
  262.     if (usaptr->ansifl&ANSON) {
  263.         prf("[%02dD", strlen(trvusr->answer));
  264.     } else {
  265.         for (x=0; x<=(strlen(trvusr->answer)-1); x++) {
  266.             prf("%c", (char)8);
  267.         }
  268.     }
  269. }
  270.  
  271. getusrinfo()    /* Get info from user btrieve database */
  272. {
  273.     int there;
  274.  
  275.     setbtv(btvusrinfo);
  276.     setmem(trvusrinfo,sizeof(struct trvusrinfo),0);
  277.     there=acqbtv(trvusrinfo, usaptr->userid, 0);
  278.     if (there == 0) {
  279.         trvusrinfo->score = 0;
  280.         trvusrinfo->plays = 0;
  281.         memcpy(trvusrinfo->userid, usaptr->userid, UIDSIZ);
  282.         insbtv(trvusrinfo);
  283.     }
  284.     trvusr->score=trvusrinfo->score;
  285.     trvusr->plays=trvusrinfo->plays;
  286. }
  287.  
  288. saveusrinfo()   /* Update info to user database file */
  289. {
  290.     int there;
  291.  
  292.     setbtv(btvusrinfo);
  293.     setmem(trvusrinfo,sizeof(struct trvusrinfo),0);
  294.     there=acqbtv(trvusrinfo, usaptr->userid, 0);
  295.     if (there == 1) {
  296.         trvusrinfo->score = trvusr->score;
  297.         trvusrinfo->plays = trvusr->plays;
  298.         updbtv(trvusrinfo);
  299.     }
  300. }
  301.  
  302. addquest()      /* Start the process of adding a question */
  303. {
  304.     btuxmt(usrnum,"");
  305.     prf("\rSelected Add Questions:\r");
  306.     prf("Type in a Question up to 79 Characters and then type '/s' on a Blank line\r");
  307.     outprf(usrnum);
  308.     usrptr->substt=10;
  309.     bgnedt(1, sizeof(trvusr->question), trvusr->question, 1, NULL);
  310. }
  311.  
  312. checkscore()    /* Check to see if user is on high score list */
  313. {
  314. int i;
  315.  
  316.     for (i=0; i <SCORENUM; i++) {
  317.         if (sameas(trvhscore->userid[i], usaptr->userid)) {
  318.             trvhscore->score[i] = trvusr->score;
  319.             if (i!=0 && trvhscore->score[i] > trvhscore->score[i-1]) {
  320.                 strcpy(trvhscore->userid[i], trvhscore->userid[i-1]);
  321.                 trvhscore->score[i] = trvhscore->score[i-1];
  322.                 trvhscore->hdate[i] = trvhscore->hdate[i-1];
  323.                 trvhscore->htime[i] = trvhscore->htime[i-1];
  324.  
  325.                 strcpy(trvhscore->userid[i-1], usaptr->userid);
  326.                 trvhscore->score[i-1]=trvusr->score;
  327.                 trvhscore->hdate[i-1]=today();
  328.                 trvhscore->htime[i-1]=now();
  329.             }
  330.             return;
  331.         }
  332.     }
  333.  
  334.     for (i=0; i < SCORENUM; i++) {
  335.         if (trvusr->score > trvhscore->score[i]) {
  336.             movmem(&trvhscore->userid[i],&trvhscore->userid[i+1],
  337.                (SCORENUM-(i+1))*UIDSIZ);
  338.             movmem(&trvhscore->score[i],&trvhscore->score[i+1],
  339.                (SCORENUM-(i+1))*sizeof(long));
  340.             movmem(&trvhscore->hdate[i],&trvhscore->hdate[i+1],
  341.                (SCORENUM-(i+1))*sizeof(int));
  342.             movmem(&trvhscore->htime[i],&trvhscore->htime[i+1],
  343.                (SCORENUM-(i+1))*sizeof(int));
  344.             strcpy(trvhscore->userid[i],usaptr->userid);
  345.             trvhscore->score[i]=trvusr->score;
  346.             trvhscore->hdate[i]=today();
  347.             trvhscore->htime[i]=now();
  348.             return;
  349.         }
  350.     }
  351. }
  352.  
  353. displayhscore() /* Display high scores to user */
  354. {
  355.     int i;
  356.  
  357.     prf("Place       Score        User-id        Date       Time \r");
  358.     prf("-----     ---------     ---------     --------     -----\r");
  359.     for (i=0 ; i < SCORENUM; i++) {
  360.         prf(" %2d       %9s     %9s     %8s     %5s\r",i+1,ltoa(trvhscore->score[i]),
  361.         trvhscore->userid[i],ncdate(trvhscore->hdate[i]),
  362.         nctime(trvhscore->htime[i]));
  363.     }
  364.     prf("\rDays Till ACT Scores Reset: %d\r\r", trvhscore->resetdays);
  365.     sendsmenu();
  366. }
  367.  
  368. vquest()        /* Get and show Validate Question */
  369. {
  370.     if (getquest('U') == 1) {
  371.         prf("\r\33[31mQuestion:\33[36m%s\r", trvusr->question);
  372.         prf("\33[31mAnswer:\33[36m%s\r", trvusr->answer);
  373.         prf("\r\rEnter \33[31mD\33[36m)elete, \33[31mS\33[36m)kip Question, \33[31mV\33[36m)alidate, \33[31mE\33[36m)xit :");
  374.     } else return(0);
  375. }
  376.  
  377. static trivia()                      /* Trivia handler  */
  378. {
  379.     char *cp;
  380.     char key;
  381.  
  382.     trvusr=(struct trvusr *)vdaptr;
  383.     setmbk(trvmb);
  384.  
  385.     if (usrptr->flags&INJOIP) {
  386.         if (trvusr->flags&TIMEOUT) {
  387.         } else {
  388.             switch(usrptr->substt) {
  389.                 case 1:
  390.                     sendsmenu();
  391.                     break;
  392.  
  393.                 case 20:
  394.                     showquest(1);
  395.                     break;
  396.  
  397.                 case 21:
  398.                     showquest(2);
  399.                     break;
  400.  
  401.                 case 22:
  402.                     showquest(3);
  403.                     break;
  404.             }
  405.             outprf(usrnum);
  406.             return(1);
  407.         }
  408.     }
  409.  
  410.     do {
  411.         bgncnc();
  412.         switch(usrptr->substt) {
  413.         case 0:
  414.             shocst(1, "%s GAME ACCESS: Trivia!", usaptr->userid);
  415.             cncchr();
  416.             sendlmenu();
  417.             if (!nlvtrv && usrptr->class < PAYING) {
  418.                 prfmsg(REJECT);
  419.                 prfmsg(GOODBY);
  420.                 return(0);
  421.             }
  422.           outprf(usrnum);
  423.           break;
  424.     case 1:
  425.           usrptr->substt=1;
  426.           key=cncchr();
  427.           if (usrptr->flags&ISYSOP) {
  428.             switch(key) {
  429.                 case 'E':
  430.                     btuxmt(usrnum,"");
  431.                     prfmsg(TMENUE);
  432.                     usrptr->substt=5;
  433.                     break;
  434.             }
  435.           }
  436.           switch(key) {
  437.             case 'I':
  438.                 usrptr->substt=60;
  439.                 btuinj(usrnum, CYCLE);
  440.                 break;
  441.  
  442.             case 'S':
  443.                 prf("\r                 High Scores!\r");
  444.                 getusrinfo();
  445.                 prf("\rName: %s\r", usaptr->userid);
  446.                 prf("Score: %s\r", ltoa(trvusr->score));
  447.                 prf("Plays Today: %d\r\r", trvusr->plays);
  448.                 displayhscore();
  449.                 break;
  450.  
  451.             case 'P':
  452.                 getusrinfo();
  453.                 if (trvusr->plays < tnplay || tnplay == 0) {
  454.                     trvusr->plays++;
  455.                     if (getquest('A') == 1) {
  456.                         showquest(1);
  457.                         usrptr->substt = 20;
  458.                         trvtime[usrnum] = trvtmout;
  459.                     } else {
  460.                         prf("\rSorry No Questions to Answer at this time!\r");
  461.                         sendsmenu();
  462.                     }
  463.                 } else {
  464.                     prf("\rSorry you may only Answer %d Questions a Day, Please call back tommorow!\r", trvusr->plays);
  465.                     sendsmenu();
  466.                 }
  467.                 break;
  468.  
  469.             case 'X': /* Exit back to main menu */
  470.                 shocst(1, "%s GAME EXIT: Trivia!", usaptr->userid);
  471.                 rstrxf();       /* Restore screen back to normal using Majorbbs.c routine */
  472.                 prfmsg(GOODBY);
  473.                 return(0);
  474.  
  475.             case '?':
  476.                 sendlmenu();
  477.                 break;
  478.  
  479.             default:
  480.                 if (usrptr->substt==1) sendsmenu();
  481.                 break;
  482.           }
  483.           outprf(usrnum);
  484.           break;
  485.  
  486.     case 2:
  487.           prfmsg(THANKS,usaptr->userid);
  488.           prfmsg(GOODBY);
  489.           shocst(1, "%s GAME EXIT: Trivia!", usaptr->userid);
  490.           return(0);
  491.  
  492.     case 5:
  493.         key=cncchr();
  494.         switch(key) {
  495.             case 'E':
  496.                 if (trvhscore->lastquest == 0 ) {
  497.                     prf("\rNo Questions Currently avalable to Edit!\r");
  498.                 }
  499.                 vmode = VMFIRST;
  500.                 usrptr->substt = 45;    /* Entering New Valadate Area */
  501.                 btuinj(usrnum, CYCLE);
  502.                 break;
  503.  
  504.             case 'A':
  505.                 addquest();
  506.                 break;
  507.  
  508.             case 'R':
  509.                 trvclean();
  510.                 trvusr->score = 0;
  511.                 prf("Reseting User Scores....\r\r");
  512.                 prfmsg(TMENUE);
  513.                 break;
  514.  
  515.             case 'X':
  516.                 sendsmenu();
  517.                 break;
  518.  
  519.             case '?':
  520.                 prfmsg(TMENUE);
  521.                 break;
  522.  
  523.             default:
  524.                 prfmsg(TMENUES);
  525.                 break;
  526.         }
  527.         outprf(usrnum);
  528.         break;
  529.  
  530.     case 9: /* Ask if want to add question to database (y/n) */
  531.         rstrxf();
  532.         key=cncyesno();
  533.         switch(key) {
  534.             case 'Y':
  535.                 addquest();
  536.                 break;
  537.  
  538.             case 'N':
  539.                 sendsmenu();
  540.                 break;
  541.  
  542.             default:
  543.                 prf("\rWould you like to enter a question (Y/N)? ");
  544.                 break;
  545.         }
  546.         outprf(usrnum);
  547.         break;
  548.  
  549.     case 10: /* Add Question Editor Status */
  550.         if (dunedt()) {
  551.             usrptr->substt=11;
  552.             btuxmt(usrnum,"");
  553.             prf("OK, Now enter the Answer to your Question.  Please use Correct spelling!\r");
  554.             outprf(usrnum);
  555.             bgnedt(1, sizeof(trvusr->answer), trvusr->answer, 1, NULL);
  556.         }
  557.         break;
  558.  
  559.     case 11: /* Add Answer Editor Status */
  560.         if (dunedt()) {
  561.             if (usrptr->flags&ISYSOP) {
  562.                 usrptr->substt=13;
  563.             } else usrptr->substt=12;
  564.             btuxmt(usrnum,"");
  565.             prf("\rQuestion:%s\r", trvusr->question);
  566.             prf("Answer:%s\r", trvusr->answer);
  567.             prf("Good, Is this OK? (Y/N):");
  568.             outprf(usrnum);
  569.         }
  570.         break;
  571.  
  572.     case 12: /* Save Question and Exit, Normal User */
  573.         if (cncchr() == 'Y') {
  574.             savequest();
  575.         }
  576.         sendsmenu();
  577.         outprf(usrnum);
  578.         break;
  579.  
  580.     case 13: /* Save Question and Exit, Sysop User */
  581.         if (cncchr() == 'Y') {
  582.             savequest();
  583.         }
  584.         prfmsg(TMENUES);
  585.         outprf(usrnum);
  586.         usrptr->substt=5;
  587.         break;
  588.  
  589.     case 20: /* ---- Ask Question and see if right! ---- */
  590.         cp = cncall();
  591.         if (sameas(cp, trvusr->answer)) {
  592.             trvusr->score += trvscor1;
  593.             saveusrinfo();
  594.             prf("\rIts RIGHT!!! You get %d Points.\r\r", trvscor1);
  595.             trvtime[usrnum] = 0;
  596.             btumil(usrnum,DFTIMX); /* Reset line length back to normal */
  597.             checkscore();
  598.             prf("\rWould you like to enter a question (Y/N)? ");
  599.             usrptr->substt=9;
  600.         } else {
  601.             showquest(2);
  602.             usrptr->substt=21;
  603.             trvtime[usrnum] = trvtmout;
  604.         }
  605.         outprf(usrnum);
  606.         break;
  607.  
  608.     case 21: /* ---- Ask Question second time and see if right ---- */
  609.         cp = cncall();
  610.         if (sameas(cp, trvusr->answer)) {
  611.             trvusr->score += trvscor2;
  612.             saveusrinfo();
  613.             prf("\rIts RIGHT!!! You get %d Points.\r\r", trvscor2);
  614.             trvtime[usrnum] = 0;
  615.             btumil(usrnum,DFTIMX); /* Reset line length back to normal */
  616.             checkscore();
  617.             prf("\rWould you like to enter a question (Y/N)? ");
  618.             usrptr->substt=9;
  619.         } else {
  620.             showquest(3);
  621.             usrptr->substt=22;
  622.             trvtime[usrnum] = trvtmout;
  623.         }
  624.         outprf(usrnum);
  625.         break;
  626.  
  627.     case 22:
  628.         cp = cncall();
  629.         prf("\rQuestion #%s", ltoa(trvhscore->curquest));
  630.         if (sameas(cp, trvusr->answer)) {
  631.             trvusr->score += trvscor3;
  632.             checkscore();
  633.             prf("\rIts RIGHT!!! You get %d Points.\r\r", trvscor3);
  634.         } else {
  635.             prf("\rSorry!!!, You did not get it right this time.\r\r");
  636.         }
  637.         trvtime[usrnum] = 0;
  638.         btumil(usrnum,DFTIMX); /* Reset line length back to normal */
  639.         saveusrinfo();
  640.         prf("\rWould you like to enter a question (Y/N)? ");
  641.         usrptr->substt=9;
  642.         outprf(usrnum);
  643.         break;
  644.  
  645.     case 40:        /* New Validation Menu and Functions */
  646.         switch(cncchr()) {
  647.             case 'N':   /* Show Next Question */
  648.                 vmode = VMNEXT;
  649.                 usrptr->substt = 45;
  650.                 btuinj(usrnum, CYCLE);
  651.                 break;
  652.  
  653.             case 'P':   /* Show Previous Question */
  654.                 vmode = VMPREV;
  655.                 usrptr->substt = 45;
  656.                 btuinj(usrnum, CYCLE);
  657.                 break;
  658.  
  659.             case 'F':   /* Find Unvalidated Questions */
  660.                 prf("\rSearching .");
  661.                 outprf(usrnum);
  662.                 vmode = VMFIND;
  663.                 usrptr->substt = 45;
  664.                 btuinj(usrnum, CYCLE);
  665.                 break;
  666.  
  667.             case 'C':   /* Change Status of Question */
  668.                 prfmsg(CSTAT);
  669.                 usrptr->substt = 50;
  670.                 outprf(usrnum);
  671.                 break;
  672.  
  673.             case 'E':   /* Edit Question for Errors */
  674.                 sprintf(trvusr->question, "%s", trvquest->question);
  675.                 sprintf(trvusr->answer, "%s", trvquest->answer);
  676.                 prfmsg(EDQST1, trvusr->question, trvusr->answer);
  677.                 usrptr->substt = 51;
  678.                 outprf(usrnum);
  679.                 break;
  680.  
  681.             case 'X':   /* Exit Back to main menu */
  682.                 prf("\r");
  683.                 sendsmenu();
  684.                 outprf(usrnum);
  685.                 break;
  686.  
  687.             default:
  688.                 prfmsg(VQUEST, trvquest->userid, ltoa(curuquest),
  689.                     trvquest->approv, trvquest->question,
  690.                     trvquest->answer);
  691.                 outprf(usrnum);
  692.                 break;
  693.           }
  694.           break;
  695.  
  696.         case 50:
  697.             switch(cncchr()) {
  698.                 case 'A':               /* Set Status to Approved */
  699.                     vmode = VMAPPR;
  700.                     usrptr->substt = 45;
  701.                     btuinj(usrnum, CYCLE);
  702.                     break;
  703.  
  704.                 case 'D':               /* Set Status to Deleted */
  705.                     vmode = VMDEL;
  706.                     usrptr->substt = 45;
  707.                     btuinj(usrnum, CYCLE);
  708.                     break;
  709.  
  710.                 case 'U':               /* Set Status to Unapproved */
  711.                     vmode = VMUNAP;
  712.                     usrptr->substt = 45;
  713.                     btuinj(usrnum, CYCLE);
  714.                     break;
  715.  
  716.                 default:                /* Don't Change the Status */
  717.                     prfmsg(VQUEST, trvquest->userid, ltoa(curuquest),
  718.                         trvquest->approv, trvquest->question,
  719.                         trvquest->answer);
  720.                     outprf(usrnum);
  721.                     usrptr->substt = 40;
  722.                     break;
  723.             }
  724.             break;
  725.  
  726.         case 51:
  727.             switch(cncchr()) {
  728.                 case '1':   /* 1 = Edit Question */
  729.                     usrptr->substt=52;
  730.                     sprintf(trvquest->question, " %s", trvusr->question);
  731.                     sprintf(trvquest->answer, " %s", trvusr->answer);
  732.                     movmem(trvquest->question, trvusr->question, sizeof(trvquest->question));
  733.                     movmem(trvquest->answer, trvusr->answer, sizeof(trvquest->answer));
  734.                     bgnedt(0, sizeof(trvusr->question), trvusr->question, 0, NULL);
  735.                     break;
  736.  
  737.                 case '2':   /* 2 = Edit Answer */
  738.                     usrptr->substt=52;
  739.                     sprintf(trvquest->question, " %s", trvusr->question);
  740.                     sprintf(trvquest->answer, " %s", trvusr->answer);
  741.                     movmem(trvquest->question, trvusr->question, sizeof(trvquest->question));
  742.                     movmem(trvquest->answer, trvusr->answer, sizeof(trvquest->answer));
  743.                     bgnedt(0, sizeof(trvusr->answer), trvusr->answer, 0, NULL);
  744.                     break;
  745.  
  746.                 case 'S':   /* Save and Exit */
  747.                     if (acqbtv(trvquest, &curuquest, 0)) {
  748.                         sprintf(trvquest->question, "%s", trvusr->question);
  749.                         sprintf(trvquest->answer, "%s", trvusr->answer);
  750.                         updbtv(trvquest);
  751.                     }
  752.                     prfmsg(VQUEST, trvquest->userid, ltoa(curuquest),
  753.                         trvquest->approv, trvquest->question,
  754.                         trvquest->answer);
  755.                     outprf(usrnum);
  756.                     usrptr->substt = 40;
  757.                     break;
  758.  
  759.                 case 'X':   /* Just Exit, Don't Save */
  760.                     prfmsg(VQUEST, trvquest->userid, ltoa(curuquest),
  761.                         trvquest->approv, trvquest->question,
  762.                         trvquest->answer);
  763.                     outprf(usrnum);
  764.                     usrptr->substt = 40;
  765.                     break;
  766.  
  767.                 default:
  768.                     prfmsg(EDQST1, trvusr->question, trvusr->answer);
  769.                     outprf(usrnum);
  770.                     break;
  771.             }
  772.             break;
  773.  
  774.         case 52:
  775.             if (dunedt()) {
  776.                 usrptr->substt = 51;
  777.                 strcpyd(trvquest->question, trvusr->question, 1, sizeof(trvusr->question));
  778.                 strcpyd(trvquest->answer, trvusr->answer, 1, sizeof(trvusr->answer));
  779.                 movmem(trvquest->question, trvusr->question, sizeof(trvquest->question));
  780.                 movmem(trvquest->answer, trvusr->answer, sizeof(trvquest->answer));
  781.                 prfmsg(EDQST1, trvusr->question, trvusr->answer);
  782.                 outprf(usrnum);
  783.             }
  784.             break;
  785.     }
  786. } while (!endcnc());
  787. return(1);
  788. }
  789.  
  790. static triviasts()
  791. {
  792.     int oba;
  793.     char buff[256];
  794.  
  795.     trvusr=(struct trvusr *)vdaptr;
  796.     setmbk(trvmb);
  797.     if (status == 249) {
  798.         trvusr->flags|=TIMEOUT;
  799.         othusn = usrnum;
  800.         prf("\r\r\33[31mTimes UP!!!!\33[36m\r");
  801.         btucli(usrnum);
  802.         injoth();
  803.         return;
  804.     }
  805.  
  806.     if (status == 240) {
  807.         switch(usrptr->substt) {
  808.             case 45:        /* Cycled Validaton Get Routine */
  809.                 setbtv(btvquest);
  810.                 if (trvhscore->lastquest == 0) {
  811.                     sendsmenu();
  812.                     return;
  813.                 }
  814.                 setmem(trvquest, sizeof(struct trvquest), 0);
  815.                 switch(vmode) {
  816.                     case VMFIRST:
  817.                         curuquest=1;
  818.                         acqbtv(trvquest, &curuquest, 0);
  819.                         prfmsg(VQUEST, trvquest->userid, ltoa(curuquest),
  820.                             trvquest->approv, trvquest->question,
  821.                             trvquest->answer);
  822.                         usrptr->substt = 40;
  823.                         break;
  824.  
  825.                     case VMNEXT:
  826.                         curuquest++;
  827.                         if (curuquest > trvhscore->lastquest) curuquest = trvhscore->lastquest;
  828.                         if (acqbtv(trvquest, &curuquest, 0)) {
  829.                             prfmsg(VQUEST, trvquest->userid, ltoa(curuquest),
  830.                                 trvquest->approv, trvquest->question,
  831.                                 trvquest->answer);
  832.                             usrptr->substt = 40;
  833.                         }
  834.                         break;
  835.  
  836.                     case VMPREV:
  837.                         curuquest--;
  838.                         if (curuquest < 1) curuquest=1;
  839.                         if (acqbtv(trvquest, &curuquest, 0)) {
  840.                             prfmsg(VQUEST, trvquest->userid, ltoa(curuquest),
  841.                                 trvquest->approv, trvquest->question,
  842.                                 trvquest->answer);
  843.                             usrptr->substt = 40;
  844.                         }
  845.                         break;
  846.  
  847.                     case VMFIND:
  848.                         if (++curuquest > trvhscore->lastquest) curuquest = trvhscore->lastquest;
  849.                         if (acqbtv(trvquest, &curuquest, 0)) {
  850.                             if (trvquest->approv != 'U') {
  851.                                 prf(".");
  852.                                 outprf(usrnum);
  853.                                 if (curuquest == trvhscore->lastquest) {
  854.                                     usrptr->substt = 40;
  855.                                 } else {
  856.                                     usrptr->substt = 45;
  857.                                     btuinj(usrnum, CYCLE);
  858.                                 }
  859.                             } else usrptr->substt = 40;
  860.                             if (usrptr->substt == 40) {
  861.                                 prfmsg(VQUEST, trvquest->userid, ltoa(curuquest),
  862.                                     trvquest->approv, trvquest->question,
  863.                                     trvquest->answer);
  864.                             }
  865.                         }
  866.                         break;
  867.  
  868.                     case VMAPPR:
  869.                     case VMUNAP:
  870.                     case VMDEL:
  871.                         if (acqbtv(trvquest, &curuquest, 0)) {
  872.                             if (vmode == VMAPPR) trvquest->approv = 'A';
  873.                             if (vmode == VMUNAP) trvquest->approv = 'U';
  874.                             if (vmode == VMDEL) trvquest->approv = 'D';
  875.                             updbtv(trvquest);
  876.                         }
  877.                         prfmsg(VQUEST, trvquest->userid, ltoa(curuquest),
  878.                             trvquest->approv, trvquest->question,
  879.                             trvquest->answer);
  880.                         usrptr->substt = 40;
  881.                         break;
  882.                 }
  883.                 outprf(usrnum);
  884.                 break;
  885.  
  886.             case 60:        /* Cycle Open Read of Instruction File. */
  887.                 if ((trvusr->tfp=fopen("trivia.ins",FOPRA)) != NULL) {
  888.                     btuoes(usrnum,1);
  889.                     btuxmt(usrnum,"");
  890.                     usrptr->substt=61;
  891.                     btuinj(usrnum, CYCLE);
  892.                 } else {
  893.                     btuxmt(usrnum,"");
  894.                     prf("Against the Clock Trivia: Can't Find Instruction File!\r");
  895.                     prf("                          Please Notify the Sysop\r\r");
  896.                     sendsmenu();
  897.                     outprf(usrnum);
  898.                     usrptr->substt=1;
  899.                 }
  900.                 break;
  901.  
  902.             case 61:
  903.                 oba=min(btuoba(usrnum), sizeof(buff));
  904.                 if (!feof(trvusr->tfp)) {
  905.                     fgets(buff, oba, trvusr->tfp);
  906.                 }
  907.                 if (feof(trvusr->tfp)) {
  908.                     fclose(trvusr->tfp);
  909.                     btuoes(usrnum, 0);
  910.                     sendsmenu();  /* Reprints short menu */
  911.                 } else {
  912.                     prf("%s",buff);
  913.                     usrptr->substt=61;
  914.                     btuinj(usrnum, CYCLE);
  915.                 }
  916.                 outprf(usrnum);
  917.                 break;
  918.  
  919.             default:
  920.                 dfsthn();
  921.                 return;
  922.         }
  923.     } else {
  924.         dfsthn();
  925.     }
  926. }
  927.  
  928. trvclean()      /* midnight cleanup routine */
  929. {
  930.     int there;
  931.     long tmplastq, tmpcurrq;
  932.  
  933.     setbtv(btvusrinfo);
  934.     setmem(trvusrinfo,sizeof(struct trvusrinfo),0);
  935.  
  936.     if (trvhscore->resetdays != 0) trvhscore->resetdays--;
  937.  
  938.     there=alobtv(trvusrinfo, 0);
  939.     if (there == 1) {
  940.         trvusrinfo->plays = 0;
  941.         if (trvhscore->resetdays == 0) trvusrinfo->score = 0;
  942.         updbtv(trvusrinfo);
  943.     }
  944.     while (qnxbtv()) {
  945.         gcrbtv(trvusrinfo, 0);
  946.         trvusrinfo->plays = 0;
  947.         if (trvhscore->resetdays == 0) trvusrinfo->score = 0;
  948.         updbtv(trvusrinfo);
  949.     }
  950.  
  951.     if (trvhscore->resetdays > scoredays || trvhscore->resetdays == 0) {
  952.         tmplastq=trvhscore->lastquest;
  953.         tmpcurrq=trvhscore->curquest;
  954.         setmem(trvhscore,sizeof(struct trvhscore),0);
  955.         trvhscore->resetdays = scoredays;
  956.         trvhscore->lastquest = tmplastq;
  957.         trvhscore->curquest = tmpcurrq;
  958.     }
  959. }
  960.  
  961. trvshd()                      /* System shutdown routine                   */
  962. {
  963.     if (trvmb != NULL) {    /* Close MSG file */
  964.         clsmsg(trvmb);
  965.         trvmb=NULL;
  966.     }
  967.     if (btvquest != NULL) { /* Update and Close Question database */
  968.         clsbtv(btvquest);
  969.     }
  970.     if (btvusrinfo != NULL) clsbtv(btvusrinfo);     /* Close user file */
  971.     if (btvhscore != NULL) {
  972.         setbtv(btvhscore);
  973.         alobtv(btvhscore->data,0);
  974.         updbtv(trvhscore);
  975.         clsbtv(btvhscore);      /* Close High Score file */
  976.     }
  977. }
  978.